#include"GnssMGR.hpp"
#include"MapApp.hpp"
#include"../Base/Concurrency/Lock.hpp"
#include<filesystem>
#include<fstream>
#include"rapidjson/document.h"

namespace SC_SUN
{

namespace Details {

    bool LoadEvGnssSNDataSubData(const std::string& path, EvGnssSNDataSub& data, uint32_t slice)
    {
        using namespace rapidjson;

        int fileLen = std::filesystem::file_size(path);
        std::string buff;
        buff.resize(fileLen);
        FILE* pf = fopen(path.data(), "rb");
        fread(buff.data(), 1, fileLen, pf);
        fclose(pf);

        Document doc;
        doc.Parse(buff.data());
        auto obj = doc.GetObj();

        data.SAT_SN = obj["GNSS_basic"].GetObj()["SAT_SN"].GetString();
        data.GNSS_ST = obj["GNSS_ST"].GetDouble();
        data.GNSS_WD = obj["GNSS_WD"].GetUint();

        //根据切片索引获取值
        auto array = obj["GNSS_Single_Info"].GetArray();
        if (array.Size() <= slice)
            return false;

        auto obj2 = array[slice].GetObj();

        //解析数据
        data.GNSS_SAT_SN = obj2["GNSS_SAT_SN"].GetString();
        data.GNSS_SAT_POS[0] = obj2["GNSS_SAT_POS"].GetArray()[0].GetDouble();
        data.GNSS_SAT_POS[1] = obj2["GNSS_SAT_POS"].GetArray()[1].GetDouble();
        data.GNSS_SAT_POS[2] = obj2["GNSS_SAT_POS"].GetArray()[2].GetDouble();
        data.GNSS_SAT_PR = obj2["GNSS_SAT_PR"].GetDouble();
        data.GNSS_SAT_RC = obj2["GNSS_SAT_RC"].GetString();
        data.GNSS_SAT_NM = obj2["GNSS_SAT_NM"].GetString();

        return true;
    }
}

int GnssManGR::LoadData()
{
    using namespace rapidjson;

    mAllSliceGNSSInfos.clear();
    mGNSSs.clear();

    int num = 0;

    //读取配置文件目录
    std::string path = mApp.CurScene() + "/Data_Summary/GNSS_Info.json";

    //读取字符串数据
    int fileLen = std::filesystem::file_size(path);
    std::string data;
    data.resize(fileLen);
    FILE* pf = fopen(path.data(), "rb");
    fread(data.data(), 1, fileLen, pf);
    fclose(pf);

    //解析json数据
    mInfo.Parse(data.data());
    auto array = mInfo.GetArray();

    for (int i = 0; i < array.Size(); i++)
    {
        auto obj = array[i].GetObj();
        EvGnssSNData gnss;

        //解析基本数据
        gnss.SAT_SN = obj["SAT_SN"].GetString();
        gnss.GNSS_TT = obj["GNSS_TT"].GetDouble();
        gnss.GNSS_STP = obj["GNSS_STP"].GetDouble();
        gnss.GNSS_NUM = obj["GNSS_NUM"].GetUint();
        gnss.PATH_SAT_SN = obj["GNSS_path"].GetString();

        //获取所有切换GNSS数据信息并保存
        auto array2 = obj["Slice_GNSS_Info"].GetArray();

        //解析0号切片数据
        auto obj2 = array2[0].GetObj();
        gnss.GNSS_SN = obj2["GNSS_SN"].GetString();
        gnss.GNSS_ST = obj2["GNSS_ST"].GetDouble();
        gnss.GNSS_WD = obj2["GNSS_WD"].GetUint();
        gnss.PATH_GNSS_SN = obj2["path"].GetString();

        //由于路径问题需要去掉一部分
        std::string path = mApp.CurScene();
        int idx = path.find_last_of('/');
        path = path.substr(0, idx + 1);

        //解析数据
        Details::LoadEvGnssSNDataSubData(path + gnss.PATH_GNSS_SN, gnss.GNSS_SN_DATA, 0);
        AddGNSS(gnss.SAT_SN, gnss);

        //保存所有数据
        mMutex.Lock();
        mAllSliceGNSSInfos.insert({gnss.SAT_SN, array2});
        mMutex.Unlock();
    }

    return num;
}

bool GnssManGR::AddGNSS(const std::string& SatSN, const EvGnssSNData& sat)
{
    MMF::LockGuard lk(mMutex);

    //不存在就开始添加
    if (mGNSSs.find(SatSN) == mGNSSs.end())
    {
        mGNSSs.insert({SatSN, sat});
        return true;
    }

    return false;
}


bool GnssManGR::FindGNSS(const std::string& SatSN)
{
    MMF::LockGuard lk(mMutex);
    return mGNSSs.find(SatSN) != mGNSSs.end();
}


EvGnssSNData* GnssManGR::GetGNSS(const std::string& SatSN, uint32_t sliceIdx)
{
    MMF::LockGuard lk(mMutex);

    //不存在就开始添加
    std::unordered_map<std::string, EvGnssSNData>::iterator it = mGNSSs.find(SatSN);
    if (it != mGNSSs.end())
    {
        //由于路径问题需要去掉一部分
        std::string path = mApp.CurScene();
        int idx = path.find_last_of('/');
        path = path.substr(0, idx + 1);

        auto iter2 = mAllSliceGNSSInfos.find(SatSN);
        if (iter2->second.Size() <= sliceIdx)
            return nullptr;
        auto obj2 = iter2->second[sliceIdx].GetObj();
        it->second.GNSS_SN = obj2["GNSS_SN"].GetString();
        it->second.GNSS_ST = obj2["GNSS_ST"].GetDouble();
        it->second.GNSS_WD = obj2["GNSS_WD"].GetUint();
        it->second.PATH_GNSS_SN = obj2["path"].GetString();
        Details::LoadEvGnssSNDataSubData(path + it->second.PATH_GNSS_SN, it->second.GNSS_SN_DATA, sliceIdx); 

        return &(it->second);
    }
    return nullptr;
}


bool GnssManGR::DeleteGNSS(const std::string& SatSN)
{
    MMF::LockGuard lk(mMutex);

    //不存在就开始添加
    std::unordered_map<std::string, EvGnssSNData>::iterator it = mGNSSs.find(SatSN);
    if (it != mGNSSs.end())
    {
        mGNSSs.erase(it);
        return true;
    }
    return false;
}


bool GnssManGR::UpdateGNSS(const std::string& SatSN, const EvGnssSNData& sat)
{
    MMF::LockGuard lk(mMutex);

    //不存在就开始添加
    std::unordered_map<std::string, EvGnssSNData>::iterator it = mGNSSs.find(SatSN);
    if (it != mGNSSs.end())
    {
        it->second = sat;
        return true;
    }
    return false;
}


void GnssManGR::GetTimeAndStep(double& time, double& step)
{
    time = mGNSSs.begin()->second.GNSS_TT;
    step = mGNSSs.begin()->second.GNSS_STP;
}


}